package com.ruoyi.teaching.service.impl;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.teaching.domain.*;
import com.ruoyi.teaching.dto.PreviewTeachingPlanDTO;
import com.ruoyi.teaching.mapper.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.teaching.service.IYaTeachingPlanService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 教学计划(课)Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-17
 */
@Service
public class YaTeachingPlanServiceImpl extends ServiceImpl<YaTeachingPlanMapper,YaTeachingPlan> implements IYaTeachingPlanService
{
    @Autowired
    private YaTeachingPlanMapper yaTeachingPlanMapper;

    @Autowired
    private YaClassMapper yaClassMapper;
    @Autowired
    private YaCourseDesignDetailMapper courseDesignDetailMapper;
    @Autowired
    private YaHolidayMapper yaHolidayMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 查询教学计划(课)
     *
     * @param id 教学计划(课)主键
     * @return 教学计划(课)
     */
    @Override
    public YaTeachingPlan selectYaTeachingPlanById(Long id)
    {
        return yaTeachingPlanMapper.selectYaTeachingPlanById(id);
    }

    /**
     * 查询教学计划(课)列表
     *
     * @param yaTeachingPlan 教学计划(课)
     * @return 教学计划(课)
     */
    @Override
    public List<YaTeachingPlan> selectYaTeachingPlanList(YaTeachingPlan yaTeachingPlan)
    {
        return yaTeachingPlanMapper.selectYaTeachingPlanList(yaTeachingPlan);
    }

    /**
     * 新增教学计划(课)
     *
     * @param yaTeachingPlan 教学计划(课)
     * @return 结果
     */
    @Override
    public int insertYaTeachingPlan(YaTeachingPlan yaTeachingPlan)
    {
        return yaTeachingPlanMapper.insertYaTeachingPlan(yaTeachingPlan);
    }

    /**
     * 修改教学计划(课)
     *
     * @param yaTeachingPlan 教学计划(课)
     * @return 结果
     */
    @Override
    public int updateYaTeachingPlan(YaTeachingPlan yaTeachingPlan)
    {
        return yaTeachingPlanMapper.updateYaTeachingPlan(yaTeachingPlan);
    }

    /**
     * 批量删除教学计划(课)
     *
     * @param ids 需要删除的教学计划(课)主键
     * @return 结果
     */
    @Override
    public int deleteYaTeachingPlanByIds(Long[] ids)
    {
        return yaTeachingPlanMapper.deleteYaTeachingPlanByIds(ids);
    }

    /**
     * 删除教学计划(课)信息
     *
     * @param id 教学计划(课)主键
     * @return 结果
     */
    @Override
    public int deleteYaTeachingPlanById(Long id)
    {
        return yaTeachingPlanMapper.deleteYaTeachingPlanById(id);
    }

    @Override
    @Transactional(readOnly = true)
    public List<YaTeachingPlan> previewYaTeachingPlan(PreviewTeachingPlanDTO previewTeachingPlanDTO) {
        List<YaTeachingPlan> result = new ArrayList<>(100);
        //获取相关配置信息
          //1.根据班级名字获取班级休息日&自习日
        String className = previewTeachingPlanDTO.getClassName();
        YaClass yaClass = yaClassMapper.selectOne(new LambdaQueryWrapper<YaClass>().eq(YaClass::getClassName, className));
        Long selfStudyDay = yaClass.getSelfStudyDay();
        Long restDay = yaClass.getRestDay();
        //2.根据课程id获取课程详细信息列表
        List<YaCourseDesignDetail> courseDesignDetails = courseDesignDetailMapper.selectList(new LambdaQueryWrapper<YaCourseDesignDetail>().eq(YaCourseDesignDetail::getCourseId,previewTeachingPlanDTO.getCourseId()));
          //3.查询起始日期以后的国家法定节假日(key:日期  value:节假日名字)
        Map<String, String> holidayMap = yaHolidayMapper
                .selectList(new LambdaQueryWrapper<YaHoliday>().ge(YaHoliday::getDate, previewTeachingPlanDTO.getBeginDate()))
                .stream().collect(Collectors.toMap(YaHoliday::getDate, YaHoliday::getDescription));

        //4.获取到班级特殊休息日和自习日还有上课日
        Map<Object, Object> specialRestDays = stringRedisTemplate.opsForHash().entries("class:restday:"+className);
        Map<Object, Object> specialSelfDays = stringRedisTemplate.opsForHash().entries("class:selfday:"+className);
        Map<Object, Object> specialWorkDays = stringRedisTemplate.opsForHash().entries("class:workday:"+className);

        //从起始日期开始排课
        String beginDate = previewTeachingPlanDTO.getBeginDate();
        //转成java8 localDate
        LocalDate  currentDate = LocalDate.parse(beginDate);
        int day = 1;

        do {
            //获取当前日期周几
            int weekday = currentDate.getDayOfWeek().getValue();
            YaTeachingPlan yaTeachingPlan = new YaTeachingPlan();
            String currentDateString = currentDate.toString();
            yaTeachingPlan.setDate(currentDateString);
            yaTeachingPlan.setClassesId(yaClass.getId());
            yaTeachingPlan.setClassName(yaClass.getClassName());
            yaTeachingPlan.setStage(previewTeachingPlanDTO.getStage());
            yaTeachingPlan.setWeekday((long)weekday);
            //判断是否国家法定节假日
            String holidayDescription = holidayMap.get(currentDateString);
            if (StringUtils.isNotEmpty(holidayDescription)) {
                yaTeachingPlan.setCourseContent(holidayDescription);
            }
            //判断是否班级特殊自习/休息
            else if(specialSelfDays.containsKey(currentDateString)){
                yaTeachingPlan.setCourseContent("班级调课自习");
            }
            else if(specialRestDays.containsKey(currentDateString)){
                yaTeachingPlan.setCourseContent("班级调课休息");
            }
            //判断是否班级正常自习/休息（并且不在班级特殊上课日中）
            else if(weekday==selfStudyDay&&!specialWorkDays.containsKey(currentDateString)){
                yaTeachingPlan.setCourseContent("正常自习");
            }
            else if(weekday==restDay&&!specialWorkDays.containsKey(currentDateString)){
                yaTeachingPlan.setCourseContent("正常休息");
            }else {
                //上课
                //先获取到对应的课程设计详情
                YaCourseDesignDetail courseDesignDetail = courseDesignDetails.get(day-1);
                yaTeachingPlan.setCourseContent(courseDesignDetail.getCourseContent());
                yaTeachingPlan.setCourseDesignDetailId(courseDesignDetail.getId());
                yaTeachingPlan.setDay((long) day++);
            }
            //调到下一天
            currentDate = currentDate.plusDays(1);
            result.add(yaTeachingPlan);
        } while (day<=courseDesignDetails.size());

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchInsertYaTeachingPlan(List<YaTeachingPlan> yaTeachingPlanList) {
        return this.saveBatch(yaTeachingPlanList, 100)?1:0;
    }

    @Override
    @Transactional(readOnly = true)
    public List<YaTeachingPlan> selectYaTeachingPlanListByClassNameAndStage(YaTeachingPlan yaTeachingPlan) {
        return yaTeachingPlanMapper.selectList(new LambdaQueryWrapper<YaTeachingPlan>()
                .eq(YaTeachingPlan::getClassName,yaTeachingPlan.getClassName())
                .eq(YaTeachingPlan::getStage,yaTeachingPlan.getStage())
        );
    }
}
